#include <stdint.h>

#define LO 0
#define MIDL 1
#define MIDH 2
#define HI 3

uint32_t invert(uint32_t val)
{
  uint8_t *from = (uint8_t *)&val;
  uint32_t inv;
  uint8_t *to = (uint8_t *)&inv;

  to[LO] = from[HI];
  to[MIDL] = from[MIDH];
  to[MIDH] = from[MIDL];
  to[HI] = from[LO];

  return inv;
}

uint32_t getNetworkAddress(uint32_t myIp, uint32_t netMask)
{
  uint32_t address;
  uint8_t *pa = (uint8_t *)&address;
  uint8_t *pip = (uint8_t *)&myIp;
  uint8_t *pm = (uint8_t *)&netMask;

  pa[LO] = pip[LO] & pm[LO];
  pa[MIDL] = pip[MIDL] & pm[MIDL];
  pa[MIDH] = pip[MIDH] & pm[MIDH];
  pa[HI] = pip[HI] & pm[HI];

  return address;
}

uint32_t getIpRange(uint32_t netMask)
{
  uint32_t range;
  uint8_t *i = (uint8_t *)&range;
  uint8_t *pm = (uint8_t *)&netMask;

  i[LO] = 255 ^ pm[LO];
  i[MIDL] = 255 ^ pm[MIDL];
  i[MIDH] = 255 ^ pm[MIDH];
  i[HI] = 255 ^ pm[HI];

  return range;
}

uint32_t current = 0;
void printNext(uint32_t netAddress, uint32_t range)
{
  uint8_t *netAddr = (uint8_t *)&netAddress;
  uint8_t *curr = (uint8_t *)&current;

  printf("%d.%d.%d.%d\n",netAddr[HI]+curr[HI],netAddr[MIDH]+curr[MIDH],netAddr[MIDL]+curr[MIDL],netAddr[LO]+curr[LO]);

  if(current == range) current = 0;
  else current++;
}

void initNetDHCP(uint32_t *myIp, uint32_t *netMask, uint32_t *netAddress, uint32_t *range)
{
  uint8_t *ptrIp = (uint8_t *)myIp;
  ptrIp[HI] = 192;
  ptrIp[MIDH] = 168;
  ptrIp[MIDL] = 25;
  ptrIp[LO] = 5;

  uint8_t *ptrMask = (uint8_t *)netMask;
  ptrMask[HI] = 255;
  ptrMask[MIDH] = 255;
  ptrMask[MIDL] = 255;
  ptrMask[LO] = 0;

  *netAddress = getNetworkAddress(*myIp,*netMask);
  *range = getIpRange(*netMask);
}

void main(void)
{
  uint32_t myIp,netMask,netAddress,range;

  initNetDHCP(&myIp,&netMask,&netAddress,&range);

  uint8_t *pa = (uint8_t *)&netAddress;
  uint8_t *pr = (uint8_t *)&range;

  printf("from %d.%d.%d.%d\n",pa[HI],pa[MIDH],pa[MIDL],pa[LO]);
  printf("to %d.%d.%d.%d\n",pa[HI]+pr[HI],pa[MIDH]+pr[MIDH],pa[MIDL]+pr[MIDL],pa[LO]+pr[LO]);

  int i;
  for(i=0;i<259;i++)
    printNext(netAddress,range);
}
